package com.fingard.dsp.bank.directbank.jscb02;

import com.fingard.constant.Format;
import com.fingard.dsp.bank.directbank.FailCode;
import com.fingard.dsp.bank.directbank.PaymentState;
import com.fingard.dsp.bank.directbank.bankInterface.IBatPayRec;
import com.fingard.dsp.bank.directbank.jscb02.util.DESUtil;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.ReqQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.RetAtsQryBatPayRec;
import com.fingard.dsp.bank.reqrespobj.batpayrec.detail.RetAtsBatPayRecDetail;
import com.fingard.io.FileHelper;
import com.fingard.net.ConnState;
import com.fingard.text.StringHelper;
import com.fingard.xml.XElement;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import java.io.File;

/**
 * 江苏银行保险代收付系统(JSCB02)批量代收付
 */
public class JSCB02BatPayRec extends JSCB02Base implements IBatPayRec {
    @Override
    public RetAtsBatPayRec d_1988_BatPay(ReqBatPayRec p_req1988) throws Exception {
        return d_BatPayRec(p_req1988);
    }

    @Override
    public RetAtsQryBatPayRec d_1998_QryBatPay(ReqQryBatPayRec p_req1998) throws Exception {
        return d_QryBatPayRec(p_req1998);
    }

    @Override
    public RetAtsBatPayRec d_9188_BatPay(ReqBatPayRec p_req9188) throws Exception {
        return d_BatPayRec(p_req9188);
    }

    @Override
    public RetAtsQryBatPayRec d_9198_QryBatPay(ReqQryBatPayRec p_req9198) throws Exception {
        return d_QryBatPayRec(p_req9198);
    }

    public RetAtsBatPayRec d_BatPayRec(ReqBatPayRec p_reqBat) throws Exception {
        RetAtsBatPayRec retAts = new RetAtsBatPayRec(p_reqBat.reqHeader);
        retAts.reqSeqID = p_reqBat.reqBatchNO;

        try {
            JSCB02Header bankHeder = new JSCB02Header();
            bankHeder.transCode = JSCB02TransCode.DEAL_1988_198801_OR_9188_918801;
            bankHeder.reqSeqID = p_reqBat.reqHeader.reqSeqID;

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeder);

            xmlWriter.writeStartElement("Body");
            xmlWriter.writeStartElement("TotalInfo");

            String tmpBatSeqNoPath = getDataFileDirectory(p_reqBat.getPayDateTime());
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                tmpBatSeqNoPath += File.separator + "BatPay";
            } else {
                tmpBatSeqNoPath += File.separator + "BatRec";
            }
            String tmpBatSeqNo = String.format("%2s", getBatSeqNo(tmpBatSeqNoPath)).replace(" ", "0");

            String groupFlag = getBankConfig().getSetValue("groupFlag", "1", "bat");

            // 扣付标记: 1扣 2 付
            String dcFlag = "";
            if ("1988".equals(p_reqBat.reqHeader.transType)) {
                dcFlag = "2";
            } else {
                dcFlag = "1";
            }

            // 文件名:(命名规则:p+3+集团股份标志+扣付标志+8位发送日期+两位序号)
            xmlWriter.writeElementString("FileName", "p3" + groupFlag + dcFlag + Format.Date8Format.format(p_reqBat.getPayDateTime()) + tmpBatSeqNo);
            xmlWriter.writeElementString("FileTotalNum", p_reqBat.totalNum);
            xmlWriter.writeElementString("FileTotalAmt", StringHelper.amountMultiply100(p_reqBat.totalAmt));
            xmlWriter.writeElementString("FilePackNum", "1");
            xmlWriter.writeElementString("IsPackNo", "1");
            xmlWriter.writeElementString("IsPackNum", p_reqBat.totalNum);
            xmlWriter.writeElementString("IsPackAmt", StringHelper.amountMultiply100(p_reqBat.totalAmt));
            xmlWriter.writeEndElement();

            StringBuilder seqNoMappingContent = new StringBuilder();

            int seqNo = 0;
            while (p_reqBat.readRecord()) {
                ++seqNo;

                seqNoMappingContent.append(p_reqBat.readedDetail.askNumber).append(",").append(seqNo).append("\r\n");

                XElement tmpXElement = new XElement("SubList", "");
                String tmpAcctNo="";
                String tmpAcctName="";
                if ("1988".equals(p_reqBat.reqHeader.transType)) {
                    tmpAcctNo=p_reqBat.readedDetail.recAct;
                    tmpAcctName=p_reqBat.readedDetail.recName;

                } else {

                    tmpAcctNo=p_reqBat.readedDetail.payAct;
                    tmpAcctName=p_reqBat.readedDetail.payName;
                }
                tmpXElement.addChild(new XElement("AcctNo", tmpAcctNo));
                tmpXElement.addChild(new XElement("AcctName", tmpAcctName));
                tmpXElement.addChild(new XElement("SystemType", "1"));
                tmpXElement.addChild(new XElement("PolNo", p_reqBat.readedDetail.sourceNoteCode));
                tmpXElement.addChild(new XElement("DcFlag", dcFlag));
                tmpXElement.addChild(new XElement("WorkDate", Format.Date8Format.format(p_reqBat.readedDetail.getPayDateTime())));
                tmpXElement.addChild(new XElement("Amount", StringHelper.amountMultiply100(p_reqBat.readedDetail.payAmount)));
                tmpXElement.addChild(new XElement("SeqNo", String.valueOf(seqNo)));
                tmpXElement.addChild(new XElement("InsurCode", ""));
                tmpXElement.addChild(new XElement("GroupFlag", ""));
                tmpXElement.addChild(new XElement("Note1", p_reqBat.readedDetail.memo));
                tmpXElement.addChild(new XElement("Note2", p_reqBat.readedDetail.useType));
                xmlWriter.writeXElement(tmpXElement);
            }
            xmlWriter.writeEndDocument();

            WriteBankLogLn2("加密前明文报文:\r\n" + xmlWriter.toXmlString());
            String tmpSaltKey=getBankConfig().getValueAsString("saltKey");
            String tmpReqEncrptMsg = new DESUtil(tmpSaltKey).encrypt(xmlWriter.toXmlString());
            WriteBankLogLn2("加密后密文报文:\r\n" + tmpReqEncrptMsg);

            WriteBankLogLn2("本地批量代收付流水映射文件内容:\r\n" + seqNoMappingContent.toString());
            String tmpSeqNoMapPath = tmpBatSeqNoPath + File.separator + p_reqBat.reqBatchNO + "_" + tmpBatSeqNo + ".txt";
            WriteBankLogLn2("本地批量代收付流水映射文件路径:" + tmpSeqNoMapPath);
            FileHelper.writeFile(tmpSeqNoMapPath, seqNoMappingContent.toString(), getCharset());

            String[] tmpStrRet = sendToBank(tmpReqEncrptMsg, bankHeder);

            if (tmpStrRet[0].length() == 0) {
                String tmpRetStr = new DESUtil(tmpSaltKey).decrypt(tmpStrRet[1]);
                WriteBankLogLn2("解密后明文报文:\r\n" + tmpRetStr);

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr, tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    retAts.respInfo = tmpBkReader.getFirstText("/Message/Head/RetDesc");
                    String tmpRetCode= tmpBkReader.getFirstText("/Message/Head/RetCode");
                    retAts.transState = tmpRetCode;
                    retAts.payInfoCode = tmpRetCode;
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else if (ConnState.FAIL.equals(tmpStrRet[0])) {
                retAts.respCode = "0";
                retAts.respInfo = tmpStrRet[1];
                retAts.transState = PaymentState.FAIL_Batch;
                retAts.payInfoCode = FailCode.E9999;
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.toString();
            WriteBankLogLn(ex);
        }

        retAts.writeRetToATS();
        return retAts;
    }

    public RetAtsQryBatPayRec d_QryBatPayRec(ReqQryBatPayRec p_reqQryBat) throws Exception {
        RetAtsQryBatPayRec retAts = new RetAtsQryBatPayRec(p_reqQryBat.reqHeader);
        retAts.reqSeqID = p_reqQryBat.reqBatchNO;

        try {
            String tmpBatSeqNoPath = getDataFileDirectory(p_reqQryBat.getBgnDateTime());
            if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                tmpBatSeqNoPath += File.separator + "BatPay";
            } else {
                tmpBatSeqNoPath += File.separator + "BatRec";
            }

            String tmpBatSeqNo = "";
            String seqNoMappingContent = "";
            File tmpSeqNoMapDir = new File(tmpBatSeqNoPath);
            if (tmpSeqNoMapDir.exists()) {
                for (File tmpSeqNoFile : tmpSeqNoMapDir.listFiles()) {
                    if (tmpSeqNoFile.getName().contains(p_reqQryBat.reqBatchNO)) {
                        tmpBatSeqNo = tmpSeqNoFile.getName().split("_")[1].replace(".txt", "");

                        WriteBankLogLn2("本地批量代收付流水映射文件路径:" + tmpSeqNoFile.getAbsolutePath());
                        seqNoMappingContent = FileHelper.readToString(tmpSeqNoFile, getCharset());
                        WriteBankLogLn2("本地批量代收付流水映射文件内容:\r\n" + seqNoMappingContent);
                    }
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = "本地未产生流水映射文件，该日无交易记录!";
                retAts.writeAfterDetail();
                return retAts;
            }

            JSCB02Header bankHeader = new JSCB02Header();
            bankHeader.transCode = JSCB02TransCode.DEAL_1998_198801_OR_9198_918801;
            bankHeader.reqSeqID = getQryTransID();

            XmlTextWriter xmlWriter = new XmlTextWriter();
            writeCommonHeader(xmlWriter, bankHeader);

            xmlWriter.writeStartElement("Body");
            xmlWriter.writeElementString("OriTransDate", Format.Date8Format.format(p_reqQryBat.getBgnDateTime()));
            xmlWriter.writeElementString("OriTransNo", p_reqQryBat.reqBatchNO);

            // 扣付标记: 1扣 2 付
            String dcFlag = "";
            if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                dcFlag = "2";
            } else {
                dcFlag = "1";
            }
            xmlWriter.writeElementString("OriFileName", "p31" + dcFlag + Format.Date8Format.format(p_reqQryBat.getBgnDateTime()) + tmpBatSeqNo);
            xmlWriter.writeElementString("OriPackNo", "1");
            xmlWriter.writeElementClosed("OriSeqNo");
            xmlWriter.writeElementClosed("Note1");
            xmlWriter.writeElementClosed("Note2");
            xmlWriter.writeEndDocument();

            WriteBankLogLn2("加密前明文报文:\r\n" + xmlWriter.toXmlString());
            String tmpSaltKey=getBankConfig().getValueAsString("saltKey");
            String tmpReqEncrptMsg = new DESUtil(tmpSaltKey).encrypt(xmlWriter.toXmlString());
            WriteBankLogLn2("加密后密文报文:\r\n" + tmpReqEncrptMsg);

            String[] tmpStrRet = sendToBank(tmpReqEncrptMsg, bankHeader);

            if (tmpStrRet[0].length() == 0) {
                String tmpRetStr = new DESUtil(tmpSaltKey).decrypt(tmpStrRet[1]);
                WriteBankLogLn2("解密后明文报文:\r\n" + tmpRetStr);

                StringBuilder tmpSbMsg = new StringBuilder();
                XmlTextReader tmpBkReader = loadBankRespXmlReader(tmpRetStr, tmpSbMsg);
                if (tmpBkReader != null) {
                    retAts.respCode = "0";
                    String tmpRespInfo=tmpBkReader.getFirstText("/Message/Head/RetDesc");
                    retAts.respInfo =tmpRespInfo ;

                    String tmpRespCode = tmpBkReader.getFirstText("/Message/Head/RetCode");
                    if ("0000".equals(tmpRespCode)) {
                        while (tmpBkReader.read("/Message/Body/SubList")) {
                            String[] tmpSeqNoArray = seqNoMappingContent.split("\r\n");
                            for (String tmpSeqNo : tmpSeqNoArray) {
                                if (StringHelper.isNullOrEmpty(tmpSeqNo)) {
                                    continue;
                                }
                                if (tmpSeqNo.split(",")[1].equals(tmpBkReader.readedXElement.getSingleText("SeqNo"))) {
                                    RetAtsBatPayRecDetail tmpRetDetail = new RetAtsBatPayRecDetail();



                                    String tmpAcctNo=tmpBkReader.readedXElement.getSingleText("AcctNo");
                                    String tmpAcctName=tmpBkReader.readedXElement.getSingleText("AcctName");


                                    if ("1998".equals(p_reqQryBat.reqHeader.transType)) {
                                        tmpRetDetail.recAct = tmpAcctNo;
                                        tmpRetDetail.recName = tmpAcctName;
                                    } else {
                                        tmpRetDetail.payAct = tmpAcctNo;
                                        tmpRetDetail.payName = tmpAcctName;
                                    }
                                    tmpRetDetail.postScript = tmpSeqNo.split(",")[0];
                                    tmpRetDetail.payAmount = StringHelper.amountDivide100(tmpBkReader.readedXElement.getSingleText("Amount"));
                                    tmpRetDetail.memo = tmpBkReader.readedXElement.getSingleText("ErrMsg");
                                    tmpRetDetail.result = tmpBkReader.readedXElement.getSingleText("ErrCode");
                                    tmpRetDetail.payInfoCode = tmpBkReader.readedXElement.getSingleText("ErrMsg");

                                    retAts.writeRetDetail(tmpRetDetail);
                                }
                            }
                        }
                    } else {
                        if ("9999".equals(tmpRespCode) && retAts.respInfo.contains("查询无记录")) {
                            if (canBeNotExist(p_reqQryBat, retAts, 45)) {
                                retAts.respCode = "0";
                                retAts.transState = StringHelper.joinNotEmpty("+", tmpRespCode, retAts.respInfo);
                                retAts.payInfoCode = retAts.respInfo;
                            }
                        } else {
                            retAts.respCode = "-1";
                            retAts.respInfo = tmpRespInfo;
                        }
                    }
                } else {
                    retAts.respCode = "-1";
                    retAts.respInfo = tmpSbMsg.toString();
                }
            } else {
                retAts.respCode = "-1";
                retAts.respInfo = tmpStrRet[1];
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            retAts.respCode = "-1";
            retAts.respInfo = ex.getMessage();
            WriteBankLogLn(ex);
        }

        retAts.writeAfterDetail();
        return retAts;
    }
}